package com.kr.weitao.util.rest.query;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.kr.weitao.exception.CommonException;
import com.kr.weitao.util.StringUtils;
import com.kr.weitao.util.rest.condition.Condition;
import com.kr.weitao.util.rest.condition.EColumnAuthority;
import com.kr.weitao.util.rest.condition.MysqlCondition;
import com.kr.weitao.util.rest.dataengine.DataDisposeEngine;
import com.kr.weitao.util.rest.datatrigger.DataAMTrigger;
import com.kr.weitao.util.rest.datatrigger.DataBMTrigger;
import com.kr.weitao.util.rest.schema.Column;
import com.kr.weitao.util.rest.schema.Function;
import com.kr.weitao.util.rest.schema.FunctionManager;
import com.kr.weitao.util.spring.SpringUtils;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/** Created by paco on 2017/06/12. */
@Log4j2
@Component
@Scope("prototype")
public class ObjectModifyUtil {
  @Autowired
  @Qualifier("mySQLDataEngine")
  DataDisposeEngine de;

  @Autowired private FunctionManager tableManager;

  @Transactional
  public long execute(JSONObject param,EColumnAuthority ec) throws CommonException {

    List<Column> user_columns = null; //用户字段权限
    Function table = null; //数据表
    JSONObject master_tableinfo = null; //主表数据
    JSONArray items = null; //明细记录
    long modifyCount = 0; //主记录ID
    long user_id = 0; //用户ID

    //region 参数判断
    //region 1、系统参数判断
    if (param == null || param.isEmpty()) {
      log.error("param is null");
      throw new CommonException("-1", "参数不能为空");
    }

    //endregion

    //region 2、获取用户信息
    if (!param.containsKey("user_id")) {
      log.error("param not has user_id,param;" + param.toJSONString());
      throw new CommonException("-3", "缺少用户信息");
    }

    user_id = param.getLongValue("user_id");
    if (user_id == 0) {
      log.error("param user_id error,param;" + param.toJSONString());
      throw new CommonException("-3", "缺少用户信息");
    }
    //endregion

    //region 3、业务参数判断
    //region 1、判断主表信息是否完整
    if (!param.containsKey("function")) {
      log.error("data not has table key:" + param);
      throw new CommonException("-3", "请选择要操作的菜单");
    }

    String table_name = param.getString("function");
    if (StringUtils.isNull(table_name)) {
      log.error("data table is null:" + param);
      throw new CommonException("-3", "请选择要操作的菜单");
    }

    table = tableManager.getByName(table_name);
    if (table == null) {
      log.error("data table object is null:" + param);
      throw new CommonException("-3", "请选择要操作的菜单");
    }

    master_tableinfo = param.getJSONObject("master_object");
    if (master_tableinfo == null || master_tableinfo.isEmpty()) {
      log.error("master_object datainfo is null:" + param);
      throw new CommonException("-3", "请维护要增加的数据");
    }
    //endregion

    //region 2、判断明细数据是否完整
    JSONArray tempitems = param.getJSONArray("items");
    JSONObject tempiteminfo = null;
    if (tempitems != null && tempitems.size() > 0) {
      int ilength = tempitems.size();
      String tempforeignTable = null;
      String tempforeignColumn = null;

      for (int i = 0; i < ilength; i++) {
        tempiteminfo = tempitems.getJSONObject(i);
        if (tempiteminfo == null || tempiteminfo.isEmpty()) {
          continue;
        }
        tempforeignTable = tempiteminfo.getString("foreign_object_name");
        if (StringUtils.isNull(tempforeignTable)) {
          log.error("item index:" + i + " foreign_object_name is null,param:" + param);
          throw new CommonException("-3", "请维护要操作的关联表");
        }

        tempforeignColumn = tempiteminfo.getString("foreign_field");
        if (StringUtils.isNull(tempforeignColumn)) {
          log.error("item index:" + i + " foreign_field is null,param:" + param);
          throw new CommonException("-3", "请维护要操作的关联字段");
        }

        items.add(tempiteminfo);
      }
    }
    //endregion
    //endregion

    //region 4、获取REDIS中的用户字段权限
    //user_columns= JSON.parseArray(user_cache.toJSONString(),Sys_Column.class);
    user_columns = table.getUserColumns(user_id, ec);
    if (user_columns == null || user_columns.size() <= 0) {
      log.error("redis user_columns is null,param;" + param.toJSONString());
      throw new CommonException("-3", "用户权限不足");
    }

    //求出接口传入的查询字段与用户权限字段的交集


    //endregion
    //endregion

    //region BM处理
    String bmclassname = table.getDataBMClassName();
    if (table.getIsBm() && StringUtils.isNotNull(bmclassname)) {
      DataBMTrigger dataBMTrigger = null;
      try {
        Class clazz=Class.forName(bmclassname);
        if(clazz.isAnnotationPresent(Component.class)){
          dataBMTrigger = (DataBMTrigger)SpringUtils.getBean(clazz);
        }else{
          dataBMTrigger = (DataBMTrigger) clazz.newInstance();
        }
      } catch (Exception e) {
        log.error("get DataBCTrigger instance error:" + e.getLocalizedMessage(), e);
        throw new CommonException("-80", "BM 配置有误");
      }

      dataBMTrigger.execute(table, param);
    }
    //endregion

    //region 主表数据处理
    //判断是否有传入主键值
    JSONObject tempMasterData = param.getJSONObject("master_object");
    long id = tempMasterData.getLongValue(table.getPK().getDb_name());
    if (id <= 0) {
      log.error("modify data id error masterdata:" + tempMasterData.toJSONString());
      throw new CommonException("-80", "请正确维护要修改的数据（主键有误）");
    }

    JSONObject modifyParam = new JSONObject();
    modifyParam.put("master_object", tempMasterData);
    modifyParam.put("user_id", param.getLongValue("user_id"));
    Condition mysqlConditeion = MysqlCondition.getInstance(table);

    modifyCount =
        de.update(
            mysqlConditeion.getUpdateSql(modifyParam, user_columns),
            mysqlConditeion.getUpdateDataParam());
    //endregion

    //region 处理明细数据
    if (items != null && items.size() > 0) {
      Function tempfortable = null; //外键关联表
      Column tempforcolumn = null; //外键关联字段
      JSONArray tempadd = null; //要新增的明细数据
      JSONArray tempmodify = null; //要修改的明细数据

      String tempforeignTableName = null; //外键关联表名称
      String tempforeignColumnName = null; //外键关联字段名称

      int ilength = items.size();

      for (int i = 0; i < ilength; i++) {
        tempiteminfo = items.getJSONObject(i);
        if (tempiteminfo == null || tempiteminfo.isEmpty()) {
          continue;
        }

        //region 判断明细参数
        tempforeignTableName = tempiteminfo.getString("foreign_object_name");
        if (StringUtils.isNull(tempforeignTableName)) {
          log.error("item index:" + i + " foreign_object_name is null,param:" + param);
          throw new CommonException("-90", "请维护要新增的明细表数据");
        }
        tempfortable = tableManager.getByName(tempforeignTableName);
        if (tempfortable == null) {
          log.error("item index:" + i + " not find foreign table by name:" + tempforeignTableName);
          throw new CommonException("-90", "请正确维护要操作的关联表");
        }

        tempforeignColumnName = tempiteminfo.getString("foreign_field");
        if (StringUtils.isNull(tempforeignColumnName)) {
          log.error("item index:" + i + " foreign_field is null,param:" + param);
          throw new CommonException("-90", "请维护要操作的关联字段");
        }
        tempforcolumn = table.getColumnByDBName(tempforeignColumnName);
        if (tempforcolumn == null) {
          log.error(
              "item index:" + i + " not find foreign column by name:" + tempforeignColumnName);
          throw new CommonException("-90", "请正确维护要操作的关联字段");
        }
        //endregion

        //region 处理明细数据

        //region 新增数据
        tempadd = tempiteminfo.getJSONArray("add_list");
        if (tempadd != null && tempadd.size() > 0) {
          int alength = tempadd.size();
          JSONObject tempAddInfo = null;
          for (int j = 0; j < alength; j++) {
            tempAddInfo = tempadd.getJSONObject(j);
            if (tempAddInfo == null || tempAddInfo.isEmpty()) {
              log.error("-80", "add foreign table:" + tempfortable.getShowName() + " data is null");
              throw new CommonException("-90", "请维护要新增的明细表（" + tempfortable.getShowName() + "）数据");
            }

            JSONObject createjo = new JSONObject();
            createjo.put("function", tempforeignTableName);
            createjo.put("master_object", tempAddInfo.getJSONObject("master_object"));
            createjo.put("items", tempAddInfo.getJSONArray("items"));
            createjo.put("user_id", user_id);

            //创建数据
            SpringUtils.getBean(ObjectCreateUtil.class).execute(createjo,EColumnAuthority.itemdate);
          }
        }
        //endregion

        //region 修改数据
        tempmodify = tempiteminfo.getJSONArray("modify_list");
        if (tempmodify == null || tempmodify.size() <= 0) {
          log.error("item index:" + i + " add_list is null,param:" + param);
          throw new CommonException("-90", "请维护要修改的明细表（" + tempfortable.getShowName() + "）数据");
        }
        if (tempmodify != null && tempmodify.size() > 0) {
          int mlength = tempmodify.size();
          JSONObject tempModifyInfo = null;
          for (int j = 0; j < mlength; j++) {
            tempModifyInfo = tempmodify.getJSONObject(j);
            if (tempModifyInfo == null || tempModifyInfo.isEmpty()) {
              log.error("-80", "add foreign table:" + tempfortable.getShowName() + " data is null");
              throw new CommonException("-90", "请维护要新增的明细表（" + tempfortable.getShowName() + "）数据");
            }

            JSONObject modifyjo = new JSONObject();
            modifyjo.put("function", tempforeignTableName);
            modifyjo.put("master_object", tempModifyInfo.getJSONObject("master_object"));
            modifyjo.put("items", tempModifyInfo.getJSONArray("items"));
            modifyjo.put("user_id", user_id);

            //修改数据
            SpringUtils.getBean(ObjectModifyUtil.class).execute(modifyjo,EColumnAuthority.itemdate);
          }
        }
        //endregion
        //endregion
      }
    }
    //endregion

    //region AM处理
    String amclassname = table.getDataAMClassName();
    if (table.getIsAm() && StringUtils.isNotNull(amclassname)) {
      DataAMTrigger dataAMTrigger = null;


      try {
        Class clazz=Class.forName(amclassname);
        if(clazz.isAnnotationPresent(Component.class)){
          dataAMTrigger = (DataAMTrigger)SpringUtils.getBean(clazz);
        }else{
          dataAMTrigger = (DataAMTrigger) clazz.newInstance();
        }
      } catch (Exception e) {
        log.error("get DataBCTrigger instance error:" + e.getLocalizedMessage(), e);
        throw new CommonException("-80", "BM 配置有误");
      }

      dataAMTrigger.execute(table, param);
    }
    //endregion

    return modifyCount;
  }
}
